package br.com.tiespec.ejb.Dao;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import br.com.tiespec.ejb.Util.DataUtils;
import br.com.tiespec.model.Enum.SituClientePortal;
import br.com.tiespec.model.Enum.TipoSortOrder;
import br.com.tiespec.model.Modelo.Usuario;

@Stateless(mappedName = "UsuarioDAO")
public class UsuarioDAO extends DAO {

	private static final long serialVersionUID = 1L;
	
	@SuppressWarnings("unchecked")
	public List<Usuario> listarUsuarioPendenteAprovacao(int first,
			int pageSize, String sortField, TipoSortOrder sortOrder,
			Long idClientePortal, String varNome, String varEmail, Date varCadastroDe,
			Date varCadastroAte) {
		List<Usuario> uList = new ArrayList<Usuario>();
		try {
			begin();
			Criteria criteria = this.session.createCriteria(Usuario.class)
					.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
					.add(Restrictions.eq("cliente", idClientePortal))
					.add(Restrictions.eq("situacao", SituClientePortal.PENDENTE_APROVACAO));
			
			if (varCadastroDe != null)
				criteria.add(Restrictions.ge("dataCadastro", DataUtils.getEmptyTime(varCadastroDe)));
			if (varCadastroAte != null)
				criteria.add(Restrictions.le("dataCadastro", DataUtils.getFullTime(varCadastroAte)));
			if (varNome != null)
				criteria.add(Restrictions.or(
						Restrictions.ilike("nomeCompleto", "%" + varNome + "%"),
						Restrictions.ilike("nomeCurto", "%" + varNome + "%")
						));
			if (varEmail != null)
				criteria.add(Restrictions.ilike("email", "%" + varEmail + "%"));
			
			criteria = montaPaginacaoSimples(criteria, first, pageSize, sortField, sortOrder);
			
			uList = criteria.list();
			commit();
			fecharConexao();
		} catch (Exception e){
			e.printStackTrace();
			fecharConexao();
		}
		return uList;
	}

	public Integer countUsuarioPendenteAprovacao(Long idClientePortal, String varNome, 
			String varEmail, Date varCadastroDe, Date varCadastroAte) {
		Integer count = 0;
		try {
			begin();
			Criteria criteria = this.session.createCriteria(Usuario.class)
					.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
					.setProjection(Projections.rowCount())
					.add(Restrictions.eq("cliente", idClientePortal))
					.add(Restrictions.eq("situacao", SituClientePortal.PENDENTE_APROVACAO));
			
			if (varCadastroDe != null)
				criteria.add(Restrictions.ge("dataCadastro", DataUtils.getEmptyTime(varCadastroDe)));
			if (varCadastroAte != null)
				criteria.add(Restrictions.le("dataCadastro", DataUtils.getFullTime(varCadastroAte)));
			if (varNome != null)
				criteria.add(Restrictions.or(
						Restrictions.ilike("nomeCompleto", "%" + varNome + "%"),
						Restrictions.ilike("nomeCurto", "%" + varNome + "%")
						));
			if (varEmail != null)
				criteria.add(Restrictions.ilike("email", "%" + varEmail + "%"));
			
			count = Integer.parseInt(criteria.uniqueResult().toString());
			
			commit();
			fecharConexao();
		} catch (Exception e){
			e.printStackTrace();
			fecharConexao();
		}
		return count;
	}
	
	@SuppressWarnings("unchecked")
	public List<Usuario> listarUsuario(int first,
			int pageSize, String sortField, TipoSortOrder sortOrder,
			String varNome) {
		List<Usuario> uList = new ArrayList<Usuario>();
		try {
			begin();
			Criteria criteria = this.session.createCriteria(Usuario.class)
					.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
					.add(Restrictions.eq("situacao", SituClientePortal.ATIVO));
			
			if (varNome != null)
				criteria.add(Restrictions.or(
						Restrictions.ilike("nomeCompleto", "%" + varNome + "%"),
						Restrictions.ilike("nomeCurto", "%" + varNome + "%")
						));
			
			criteria = montaPaginacaoSimples(criteria, first, pageSize, sortField, sortOrder);
			
			uList = criteria.list();
			commit();
			fecharConexao();
		} catch (Exception e){
			e.printStackTrace();
			fecharConexao();
		}
		return uList;
	}

	public Integer countUsuario(String varNome) {
		Integer count = 0;
		try {
			begin();
			Criteria criteria = this.session.createCriteria(Usuario.class)
					.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
					.setProjection(Projections.rowCount())
					.add(Restrictions.eq("situacao", SituClientePortal.ATIVO));
			
			if (varNome != null)
				criteria.add(Restrictions.or(
						Restrictions.ilike("nomeCompleto", "%" + varNome + "%"),
						Restrictions.ilike("nomeCurto", "%" + varNome + "%")
						));
			
			count = Integer.parseInt(criteria.uniqueResult().toString());
			
			commit();
			fecharConexao();
		} catch (Exception e){
			e.printStackTrace();
			fecharConexao();
		}
		return count;
	}

	public Usuario selecionarUsuario(Long id) {
		Usuario usuarioInstance = new Usuario(); 
		try {
			begin();
			usuarioInstance = (Usuario) this.session.createCriteria(Usuario.class)
				.add(Restrictions.eq("id", id))
				.uniqueResult();
			commit();
			fecharConexao();
		} catch (Exception e){
			e.printStackTrace();
			fecharConexao();
		}
		return usuarioInstance;
	}
	
	public Usuario selecionarUsuarioComCliente(Long id) {
		Usuario usuarioInstance = new Usuario(); 
		try {
			begin();
			usuarioInstance = (Usuario) this.session.createCriteria(Usuario.class)
				.setFetchMode("cliente", FetchMode.JOIN)
				.add(Restrictions.eq("id", id))
				.uniqueResult();
			commit();
			fecharConexao();
		} catch (Exception e){
			e.printStackTrace();
			fecharConexao();
		}
		return usuarioInstance;
	}
	
	public Usuario selecionarUsuarioComClienteEPerfil(Long id) {
		Usuario usuarioInstance = new Usuario(); 
		try {
			begin();
			usuarioInstance = (Usuario) this.session.createCriteria(Usuario.class)
				.setFetchMode("cliente", FetchMode.JOIN)
				.setFetchMode("perfil", FetchMode.JOIN)
				.add(Restrictions.eq("id", id))
				.uniqueResult();
			commit();
			fecharConexao();
		} catch (Exception e){
			e.printStackTrace();
			fecharConexao();
		}
		return usuarioInstance;
	}
	
	@SuppressWarnings("unchecked")
	public List<Usuario> listarUsuario(int first, int pageSize,
			String sortField, TipoSortOrder sortOrder, String nome,
			String email, String cliente) {
		List<Usuario> uList = new ArrayList<Usuario>();
		try {
			begin();
			Criteria criteria = this.session.createCriteria(Usuario.class)
					.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
			
			if (isNullOrBlank(nome))
				criteria.add(Restrictions.or(
							Restrictions.ilike("nomeCompleto", "%" + nome + "%"),
							Restrictions.ilike("nomeCurto", "%" + nome + "%")
						));
			if (isNullOrBlank(email))
				criteria.add(Restrictions.ilike("email", "%" + email + "%"));
			if (isNullOrBlank(cliente))
				criteria.add(Restrictions.or(
							Restrictions.ilike("cliente.nomeCompleto", "%" + cliente + "%"),
							Restrictions.ilike("cliente.nomeCurto", "%" + cliente + "%")
						));
			
			criteria = montaPaginacaoSimples(criteria, first, pageSize, sortField, sortOrder);
			
			uList = criteria.list();
			commit();
			fecharConexao();
		} catch (Exception e){
			e.printStackTrace();
			fecharConexao();
		}
		return uList;
	}

	public int countUsuario(String nome, String email, String cliente) {
		Integer count = 0;
		try {
			begin();
			Criteria criteria = this.session.createCriteria(Usuario.class)
					.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
					.setProjection(Projections.rowCount());
			
			if (isNullOrBlank(nome))
				criteria.add(Restrictions.or(
							Restrictions.ilike("nomeCompleto", "%" + nome + "%"),
							Restrictions.ilike("nomeCurto", "%" + nome + "%")
						));
			if (isNullOrBlank(email))
				criteria.add(Restrictions.ilike("email", "%" + email + "%"));
			if (isNullOrBlank(cliente))
				criteria.add(Restrictions.or(
							Restrictions.ilike("cliente.nomeCompleto", "%" + cliente + "%"),
							Restrictions.ilike("cliente.nomeCurto", "%" + cliente + "%")
						));
			
			count = Integer.parseInt(criteria.uniqueResult().toString());
			commit();
			fecharConexao();
		} catch (Exception e){
			e.printStackTrace();
			fecharConexao();
		}
		return count;
	}

	public Integer countUsuarioDeUmCliente(Long idClientePortal) {
		Integer count = 0;
		try {
			begin();
			Criteria criteria = this.session.createCriteria(Usuario.class)
					.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
					.setProjection(Projections.rowCount())
					.add(Restrictions.eq("cliente.id", idClientePortal));
			
			count = Integer.parseInt(criteria.uniqueResult().toString());
			commit();
			fecharConexao();
		} catch (Exception e){
			e.printStackTrace();
			fecharConexao();
		}
		return count;
	}

	public Usuario selecionarUsuario(String email, String senha) {
		Usuario usuarioInstance = new Usuario(); 
		try {
			begin();
			usuarioInstance = (Usuario) this.session.createCriteria(Usuario.class)
				.add(Restrictions.eq("email", email))
				.add(Restrictions.eq("senha", senha))
				.setFetchMode("perfil", FetchMode.JOIN)
				.createCriteria("cliente")
				.createCriteria("confDescricaoEstendida")
				.setFetchMode("plano", FetchMode.JOIN)
				.uniqueResult();
			commit();
			fecharConexao();
		} catch (Exception e){
			e.printStackTrace();
			fecharConexao();
		}
		return usuarioInstance;
	}

}